namespace org.jawk.ext
{
	/// <summary>Base class of various extensions.</summary>
	/// <remarks>
	/// Base class of various extensions.
	/// <p>
	/// Provides functionality common to most extensions,
	/// such as vm and jrt variable management, and convenience
	/// methods such as checkNumArgs() and toAwkString().
	/// </remarks>
	public abstract class AbstractExtension : org.jawk.ext.IJawkExtension
	{
		protected org.jawk.jrt.JRT jrt;

		protected org.jawk.jrt.IVariableManager vm;

		public virtual void Init(org.jawk.jrt.IVariableManager vm, org.jawk.jrt.JRT jrt)
		{
			this.vm = vm;
			this.jrt = jrt;
		}

		/// <summary>
		/// Convert a Jawk variable to a Jawk string
		/// based on the value of the CONVFMT variable.
		/// </summary>
		/// <remarks>
		/// Convert a Jawk variable to a Jawk string
		/// based on the value of the CONVFMT variable.
		/// </remarks>
		/// <param name="obj">The Jawk variable to convert to a Jawk string.</param>
		/// <returns>
		/// A string representation of obj after CONVFMT
		/// has been applied.
		/// </returns>
		protected string ToAwkString(object obj)
		{
			return org.jawk.jrt.JRT.ToAwkString(obj, vm.GetCONVFMT().ToString());
		}

		/// <summary>
		/// Assume no guarantee of any extension parameter being an
		/// associative array.
		/// </summary>
		/// <remarks>
		/// Assume no guarantee of any extension parameter being an
		/// associative array.
		/// </remarks>
		/// <param name="extension_keyword">The extension keyword to check.</param>
		/// <param name="arg_count">
		/// The number of actual parameters used in this
		/// extension invocation.
		/// </param>
		public virtual int[] GetAssocArrayParameterPositions(string extension_keyword, int
			 arg_count)
		{
			return new int[0];
		}

		/// <summary>
		/// Verifies that an exact number of arguments
		/// has been passed in by checking the length
		/// of the argument array.
		/// </summary>
		/// <remarks>
		/// Verifies that an exact number of arguments
		/// has been passed in by checking the length
		/// of the argument array.
		/// </remarks>
		/// <param name="arr">The arguments to check.</param>
		/// <param name="expected_num">The expected number of arguments.</param>
		/// <exception cref="org.jawk.jrt.IllegalAwkArgumentException">
		/// if the number of arguments
		/// do not match the expected number of arguments.
		/// </exception>
		protected static void CheckNumArgs(object[] arr, int expected_num)
		{
			// some sanity checks on the arguments
			// (made into assertions so that
			// production code does not perform
			// these checks)
			//assert arr != null;
			//assert expected_num >= 0;
			if (arr.Length != expected_num)
			{
				throw new org.jawk.jrt.IllegalAwkArgumentException("Expecting " + expected_num + 
					" arg(s), got " + arr.Length);
			}
		}

		public abstract string[] ExtensionKeywords();

		public abstract string GetExtensionName();

		public abstract object Invoke(string arg1, object[] arg2);
	}
}
